﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Huayuan.Manage.Controllers;
using Hyt.Core;
using Hyt.Core.Security;

namespace Huayuan.Manage.Common
{

    /// <summary>
    /// 当错误时返回类型
    /// </summary>
    public enum ErrorReturnType
    {
        Text,
        NormalJson,
        TreeJson
    }

    public class BaseController : Controller,IAop
    {

        /// <summary>
        /// 返回通用错误JSON
        /// </summary>
        private ErrorReturnType _returntype = ErrorReturnType.Text;

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            _returntype = ErrorReturnType.Text;
            var name = filterContext.ActionDescriptor.ActionName;
            var type = filterContext.Controller.GetType();
            MethodInfo minfo = null;
            if (!filterContext.ActionDescriptor.GetParameters().Any())
            {
                minfo = type.GetMethod(name, new Type[] { });
            }
            else
            {
                var ts = new List<Type>();
                foreach (var p in filterContext.ActionDescriptor.GetParameters())
                {
                    ts.Add(p.ParameterType);
                }
                minfo = type.GetMethod(name, ts.ToArray());
            }
            if (minfo.ReturnType == typeof(JsonResult))
            {
                _returntype = ErrorReturnType.NormalJson;
            }
            if (!typeof(LoginController).IsAssignableFrom(type))
            {
                using (var ufw = new WebUnitOfWork())
                {
                    if (ufw.GetCurrentPrincipal() == Principal.Anonymous)
                    {
                        if (_returntype == ErrorReturnType.NormalJson)
                        {
                            filterContext.Result = new JsonResult
                            {
                                Data = new
                                {
                                    success = false,
                                    errmsg = "请重新登录"
                                }
                            };
                        }
                        else
                        {
                            filterContext.Result = new ContentResult { Content = "请重新登录...<script>setTimeout(function(){location.href='/Login';},3000)</script>" };
                        }
                        return;
                    }
                    ufw.Commit();
                }
            }
            base.OnActionExecuting(filterContext);
        }

        /* */
        protected override void OnException(ExceptionContext filterContext)
        {
            //if (filterContext.IsChildAction)
            //{
            //    base.OnException(filterContext);
            //    return;
            //}
            var exp = GetRealException(filterContext.Exception);

            if (ExceptionHandler != null)
            {
                
                filterContext.ExceptionHandled = true;
                filterContext.Result = ExceptionHandler(exp);
                return;
            }

            if (_returntype == ErrorReturnType.NormalJson)
            {
                // 标记异常已处理
                filterContext.ExceptionHandled = true;
                ExcuteNormalJsonException(filterContext, exp);
            }
            else
            {
                if (filterContext.IsChildAction)
                {
                    base.OnException(filterContext);
                }
                else
                {
                    // 标记异常已处理
                    filterContext.ExceptionHandled = true;
                    filterContext.Result = ErrorView(exp.Message);
                }
            }
        }
       
        private void ExcuteNormalJsonException(ExceptionContext filterContext, Exception exp)
        {
            filterContext.Result = new JsonResult
            {
                Data = new
                {
                    success = false,
                    message = exp.Message
                }
            };
        }

        private Exception GetRealException(Exception exp)
        {
            if (exp.InnerException != null)
            {
                return exp.InnerException;
            }
            if (exp is TargetInvocationException)
            {
                return GetRealException((exp as TargetInvocationException).InnerException);
            }
            else
            {
                return exp;
            }
        }

        public Func<Exception, ActionResult> ExceptionHandler { get; set; }

        public void RegisterExceptionHandler(Func<Exception, ActionResult> handler)
        {
            ExceptionHandler = handler;
        }
        
        protected ViewBagObject VBO
        {
            get
            {
                var o = ViewBag.ViewBagObject;
                if (o == null)
                {
                    o = new ViewBagObject();
                    ViewBag.ViewBagObject = o;
                }
                return o;
            }
        }

        #region VBO方法
        protected void FormTo(string actionurl)
        {
            VBO.FormAction = actionurl;
        }
        protected void NotifyOpenner(string intent)
        {
            VBO.NotifyOpennerIntent = intent;
        }
        #endregion

        #region 跳转
        public ActionResult SuccessView(string text, params Huayuan.Manage.Models.Util.SuccessModel.Button[] buttons)
        {
            object area = this.RouteData.DataTokens["area"];
            if (area == null || string.IsNullOrWhiteSpace(area.ToString()))
            {
                return View("Common/Success", new Huayuan.Manage.Models.Util.SuccessModel
                {
                    Message = text,
                    Buttons = buttons.ToList()
                });
            }
            else
            {
                return View("../Common/Success", new Huayuan.Manage.Models.Util.SuccessModel
                {
                    Message = text,
                    Buttons = buttons.ToList()
                });

            }
        }


        public ActionResult ErrorView(string text)
        {
            object area = this.RouteData.DataTokens["area"];
            if (area == null || string.IsNullOrWhiteSpace(area.ToString()))
            {
                return View("Common/Error", new Huayuan.Manage.Models.Util.ErrorModel
                {
                    Message = text
                });
            }
            else
            {
                return View("../Common/Error", new Huayuan.Manage.Models.Util.ErrorModel
                {
                    Message = text
                });

            }
        }
        #endregion

        #region 提示信息
        public void Error(string msg, int? closetime = null)
        {
            VBO.ErrorInfo = msg;
            VBO.ErrorInfoCloseInfoTimeOut = closetime;
        }
        public void Warning(string msg, int? closetime = null)
        {
            VBO.WarningInfo = msg;
            VBO.WarningInfoCloseInfoTimeOut = closetime;
        }
        public void Prompt(string msg, int? closetime = null)
        {
            VBO.PromptInfo = msg;
            VBO.PromptInfoCloseInfoTimeOut = closetime;
        }
        #endregion
    }


}